package com.lion.common.spring.openapi.customizers.openapi;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Chris Chan
 * Create On 2025/10/2 上午11:23
 * Use for: 为Tag添加排序
 * Explain: 排序值越小，越靠前
 */
@Component
@Order(1900) // 确保在其他自定义器之前执行
public class TagSortingOpenApiCustomizer implements OpenApiCustomizer {
    private static final Logger log = LoggerFactory.getLogger(TagSortingOpenApiCustomizer.class);

    @Override
    public void customise(OpenAPI openApi) {
        log.info("TagSortingOpenApiCustomizer~~");
        if (openApi.getTags() == null || openApi.getTags().isEmpty()) {
            return;
        }

        //log.info("开始排序 Tags...");

        // 收集所有操作的 Tag Order 信息
        Map<String, Integer> tagOrderMap = collectTagOrders(openApi);

        // 排序 Tags
        List<Tag> sortedTags = sortTags(openApi.getTags(), tagOrderMap);

        // 设置排序后的 Tags
        openApi.setTags(sortedTags);

        //log.info("Tags 排序完成，共 {} 个 Tag", sortedTags.size());
        //log.info("排序结果: {}", sortedTags.stream().map(Tag::getName).collect(Collectors.toList()));
    }

    /**
     * 收集所有 Tag 的 Order 值
     */
    private Map<String, Integer> collectTagOrders(OpenAPI openApi) {
        Map<String, Integer> tagOrderMap = new HashMap<>();
        Map<String, Integer> tagCountMap = new HashMap<>();

        if (openApi.getPaths() != null) {
            openApi.getPaths().forEach((path, pathItem) -> {
                pathItem.readOperationsMap().forEach((httpMethod, operation) -> {
                    // 获取扩展属性中的 order 值
                    Map<String, Object> extensions = operation.getExtensions();
                    if (extensions != null) {
                        Integer order = (Integer) extensions.get("x-tag-order");
                        String tagName = (String) extensions.get("x-tag-name");

                        if (order != null && tagName != null) {
                            // 处理同一个 Tag 有多个不同 Order 值的情况
                            // 使用最小的 Order 值，或者可以改为平均值等策略
                            tagOrderMap.merge(tagName, order, Math::min);
                            tagCountMap.merge(tagName, 1, Integer::sum);
                        }
                    }
                });
            });
        }

        // 记录统计信息
        tagOrderMap.forEach((tagName, order) -> {
            log.debug("Tag '{}' 的 Order: {} (出现 {} 次)", tagName, order, tagCountMap.get(tagName));
        });

        return tagOrderMap;
    }

    /**
     * 排序 Tags
     */
    private List<Tag> sortTags(List<Tag> originalTags, Map<String, Integer> tagOrderMap) {
        List<Tag> tags = originalTags.stream()
                .sorted(createTagComparator(tagOrderMap))
                .collect(Collectors.toList());

        return tags;
    }

    /**
     * 创建 Tag 比较器
     */
    private Comparator<Tag> createTagComparator(Map<String, Integer> tagOrderMap) {
        return (tag1, tag2) -> {
            String name1 = tag1.getName();
            String name2 = tag2.getName();

            Integer order1 = tagOrderMap.get(name1);
            Integer order2 = tagOrderMap.get(name2);

            // 如果都有 Order 值，按 Order 排序
            if (order1 != null && order2 != null) {
                return Integer.compare(order1, order2);
            }

            // 如果只有一个有 Order 值，有 Order 的排在前面
            if (order1 != null) {
                return -1;
            }
            if (order2 != null) {
                return 1;
            }

            // 都没有 Order 值，按名称排序
            return name1.compareTo(name2);
        };
    }
}